package hn.cch.redisson.service;

import hn.cch.redisson.constant.RedissonConstant;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.IntegerCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.concurrent.ForkJoinPool;

@Service
public class RedissonServiceImpl implements RedissonService {

    private static final Logger logger = LoggerFactory.getLogger(RedissonServiceImpl.class);

    @Autowired
    private RedissonClient redissonClient;

    public boolean isExists(String keyName) {
        RBucket<Object> bucket = redissonClient.getBucket(keyName);
        return bucket.isExists();
    }

    public void setString(String keyName, String value) {
        RBucket<String> bucket = redissonClient.getBucket(keyName);
        bucket.set(value, Duration.ofSeconds(RedissonConstant.expireTime));
    }

    public String getString(String keyName) {
        RBucket<String> bucket = redissonClient.getBucket(keyName);
        return bucket.get();
    }

    public void setInteger(String keyName, Integer value) {
        RBucket<Integer> bucket = redissonClient.getBucket(keyName, new IntegerCodec());
        bucket.set(value, Duration.ofSeconds(RedissonConstant.expireTime));
    }

    public Integer getInteger(String keyName) {
        RBucket<Integer> bucket = redissonClient.getBucket(keyName, new IntegerCodec());
        return bucket.get();
    }

    /**
     * 自增
     *
     * @param keyName 键
     * @return
     */
    public boolean increment(String keyName) {
        RBucket<Integer> bucket = redissonClient.getBucket(keyName, new IntegerCodec());
        Integer integer = bucket.get();
        return bucket.compareAndSet(integer, integer + 1);
    }

    /**
     * 获取分布式锁，并使用线程池执行
     *
     * @param lockKey
     * @param runnable
     */
    public void useDistributedLock(String lockKey, Runnable runnable) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            lock.lock();
            logger.info("redis lock success");
            ForkJoinPool.commonPool().execute(runnable);
            logger.info("new thread run success");
        } finally {
            lock.unlock();
            logger.info("redis unlock success");
        }


    }
}
